package com.zhixinglu.spring.boot.thread.threadpool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.*;

/**
 * <p>
 * 包含线程名称线程池工具类
 * </p>
 *
 * @author weixin
 * @date 2023/3/24 14:38
 */
@Slf4j
@Component
public class NamedThreadPool {

    private static final int CPU_CORE_SIZE = Runtime.getRuntime().availableProcessors();

    private static final int MAX_POOL_SIZE = CPU_CORE_SIZE * 2;

    private static final long KEEP_ALIVE_TIME = 60L;

    private ThreadPoolExecutor executor;

    @PostConstruct
    public void init() {
        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "4");
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        executor = new ThreadPoolExecutor(availableProcessors, availableProcessors * 2, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                new CustomizableThreadFactory("test-pool-"),
                (r, executor) -> {
                    log.warn("Task {} rejected from {}", r.toString(), executor.toString());
                    throw new RejectedExecutionException("Task " + r + " rejected from " + executor);
                });
    }

    public void execute(Runnable task, String threadName) {
        executor.execute(new NamedRunnable(task, threadName));
    }

    public void shutdown() {
        if (executor != null) {
            executor.shutdown();
        }
    }

}
